<template>
  <draggable :list="dataSource" group="components" class="draggable-box" @end="end">
    <template #item="{ element: item }">
      <div class="item-box">
        <el-icon class="move"><Rank /></el-icon>
        <LowCode :schema="item" />
        <el-space class="right">
          <el-icon class="edit" @click="updateOperation(item)"><Edit /></el-icon>
          <el-icon @click.stop="deleteOperation(item.index)" class="delete"><Delete /></el-icon>
        </el-space>
      </div>
    </template>
  </draggable>
  <el-row style="width: 100%; margin-top: 10px" type="flex" justify="center" align="middle">
    <LowCode :schema="addSchema" />
  </el-row>
  <el-divider></el-divider>
</template>

<script setup>
import { ref, watchEffect } from 'vue'
import { Rank, Edit, Delete } from '@element-plus/icons-vue'
import draggable from 'vuedraggable'
import { comDescMap, inputOptions } from '@/visitual-editor/comDesc'
import LowCode from '@/components/LowCode.vue'
import { v4 as uuid } from 'uuid'
import { DrawerService } from '@/core/hook/drawer-service'
import { inputProps } from '@/visitual-editor/props'
import { VisualEditorPropsType } from '@/visitual-editor/props.util.lowcode'
import { isDef } from '@/utils'

const emit = defineEmits(['childrenChange'])
const props = defineProps({
  schema: {
    type: Object,
    required: true
  }
})

const dataSource = ref(props.schema.body)
const addSchema = {
  type: 'button',
  level: 'primary',
  body: '+子元素',
  actionType: 'dialog',
  dialog: {
    title: '新增子元素',
    width: '500px',
    body: {
      type: 'form',
      rules: {
        type: [
          {
            required: true,
            message: '请选择元素类型'
          }
        ],
        inputType: [
          {
            required: true,
            message: '请选择input类型'
          }
        ],
      },
      body: [
        {
          type: 'select',
          label: '选择元素',
          prop: 'type',
          options: [
            {
              label: comDescMap['input'],
              value: 'input'
            }
          ]
        },
        {
          type: 'select',
          label: 'input类型',
          prop: 'inputType',
          visibleOn: '${type} === "input"',
          options: inputOptions
        },
        {
          type: 'input-text',
          label: 'label',
          prop: 'label',
          visibleOn: '${type} === "input"'
        }
      ]
    },
    confirmButton: {
      type: 'button',
      actionType: 'validate',
      level: 'primary',
      body: '确认',
      validateResolve: (values) => {
        dataSource.value.push({ ...values, key: uuid() })
      }
    }
  }
}

watchEffect(() => {
  dataSource.value = props.schema.body
})

function end() {
  emit('childrenChange')
}
function updateOperation(item) {
  const body = []
  if (item.body && Array.isArray(item.body)) {
    body.push({
      type: 'list',
      body: item.body,
      labelWidth: '0px'
    })
  }
  for (const [key, value] of Object.entries(inputProps)) {
    const prop = { prop: key }
    if (value.type === VisualEditorPropsType.input) {
      prop.type = 'input-text'
    } else if (value.type === VisualEditorPropsType.select) {
      prop.type = 'select'
    } else if (value.type === VisualEditorPropsType.switch) {
      prop.type = 'switch'
    }
    prop.defaultValue = isDef(item[key]) ? item[key] : value.defaultValue
    prop.label = value.label
    body.push(prop)
  }
  DrawerService({
    title: `修改${item.label}`,
    width: '800px',
    body: {
      type: 'form',
      rules: {
        type: [
          {
            required: true,
            message: '请选择元素类型'
          }
        ]
      },
      body
    },
    confirmButton: {
      type: 'button',
      actionType: 'validate',
      level: 'primary',
      body: '修改',
      validateResolve: (values) => {
        item = Object.assign(item, values)
      }
    }
  })
}
function deleteOperation(index) {
  dataSource.value.splice(index, 1)
}
</script>
<style lang="scss" scoped>
.draggable-box {
  width: 100%;
  box-sizing: border-box;
  border: 1px solid var(--el-bg-color-page);
  padding: 10px;
  .item-box {
    position: relative;
    .move,
    .right {
      position: absolute;
      top: 50%;
      transform: translateY(-50%);
      display: none;
    }
    .move {
      left: 0;
    }
    .right {
      right: 0;
    }
    &:hover {
      .move,
      .right {
        display: inline-flex;
      }
    }
  }
}
.edit,
.delete {
  cursor: pointer;
  font-size: 18px;
}
.move {
  cursor: move;
  color: var(--el-color-primary);
  font-size: 20px;
}
.edit {
  color: var(--el-color-primary);
}
.delete {
  color: var(--el-color-danger);
}
</style>
